//go:build windows

package collector

import (
	"fmt"
	"strings"

	"sysinfo/internal/types"
	"sysinfo/internal/utils"

	"github.com/yusufpapurcu/wmi"
)

// Win32DiskDrive 表示Windows WMI磁盘驱动器信息
type Win32DiskDrive struct {
	Caption           string
	DeviceID          string
	Model             string
	SerialNumber      string
	Size              uint64
	MediaType         string
	InterfaceType     string
	Partitions        uint32
	BytesPerSector    uint32
	SectorsPerTrack   uint32
	TotalCylinders    uint64
	TotalHeads        uint32
	TotalSectors      uint64
	TotalTracks       uint64
	TracksPerCylinder uint32
	Status            string
	Index             uint32
	FirmwareRevision  string
}

// MSFT_PhysicalDisk 表示Windows存储空间物理磁盘信息（Windows 8+）
type MSFT_PhysicalDisk struct {
	FriendlyName      string
	SerialNumber      string
	MediaType         uint16 // 0=未指定, 3=HDD, 4=SSD, 5=SCM
	BusType           uint16 // 0=未知, 1=SCSI, 2=ATAPI, 3=ATA, 4=1394, 5=SSA, 6=FC, 7=USB, 8=RAID, 9=iSCSI, 10=SAS, 11=SATA, 12=SD, 13=MMC, 14=虚拟, 15=文件支持虚拟, 16=存储空间, 17=NVMe, 18=SCM
	CanPool           bool
	Size              uint64
	AllocatedSize     uint64
	OperationalStatus uint16
	HealthStatus      uint16
	Usage             uint16
	SpindleSpeed      uint32 // RPM
}

func collectPhysicalDisksPlatform() []types.PhysicalDisk {
	// 首先尝试现代的MSFT_PhysicalDisk（Windows 8+）
	modernDisks := collectDisksMSFT()
	if len(modernDisks) > 0 {
		return modernDisks
	}

	// 回退到Win32_DiskDrive（兼容旧版Windows）
	return collectDisksWMI()
}

// collectDisksMSFT 使用MSFT_PhysicalDisk获取现代Windows系统的磁盘信息
func collectDisksMSFT() []types.PhysicalDisk {
	var wmiDisks []MSFT_PhysicalDisk
	query := "SELECT * FROM MSFT_PhysicalDisk"

	// 查询root\Microsoft\Windows\Storage命名空间
	err := wmi.QueryNamespace(query, &wmiDisks, `root\Microsoft\Windows\Storage`)
	if err != nil {
		// MSFT_PhysicalDisk不可用（Windows 8之前版本或访问被拒绝）
		return nil
	}

	disks := make([]types.PhysicalDisk, 0)
	for _, wmiDisk := range wmiDisks {
		disk := types.PhysicalDisk{
			Name:          wmiDisk.FriendlyName,
			Model:         wmiDisk.FriendlyName,
			SerialNumber:  strings.TrimSpace(wmiDisk.SerialNumber),
			Size:          wmiDisk.Size,
			SizeFormatted: utils.FormatBytes(wmiDisk.Size),
		}

		// 映射媒体类型
		switch wmiDisk.MediaType {
		case 3:
			disk.Type = "HDD"
			if wmiDisk.SpindleSpeed > 0 {
				disk.RPM = wmiDisk.SpindleSpeed
			}
		case 4:
			disk.Type = "SSD"
		case 5:
			disk.Type = "SCM" // 存储类内存
		default:
			disk.Type = "Unknown"
		}

		// 映射总线类型到接口
		disk.Interface = mapBusType(wmiDisk.BusType)

		// NVMe检测
		if wmiDisk.BusType == 17 {
			disk.Type = "NVMe"
			disk.Interface = "NVMe"
		}

		// 可移动媒体检查（USB、SD、MMC）
		if wmiDisk.BusType == 7 || wmiDisk.BusType == 12 || wmiDisk.BusType == 13 {
			disk.Removable = true
		}

		disks = append(disks, disk)
	}

	return disks
}

// collectDisksWMI 使用Win32_DiskDrive获取旧版Windows系统的磁盘信息
func collectDisksWMI() []types.PhysicalDisk {
	var wmiDisks []Win32DiskDrive
	query := "SELECT * FROM Win32_DiskDrive"

	err := wmi.Query(query, &wmiDisks)
	if err != nil {
		return nil
	}

	disks := make([]types.PhysicalDisk, 0)
	for _, wmiDisk := range wmiDisks {
		disk := types.PhysicalDisk{
			Name:          wmiDisk.DeviceID,
			Model:         strings.TrimSpace(wmiDisk.Model),
			SerialNumber:  strings.TrimSpace(wmiDisk.SerialNumber),
			Size:          wmiDisk.Size,
			SizeFormatted: utils.FormatBytes(wmiDisk.Size),
			Interface:     strings.ToUpper(wmiDisk.InterfaceType),
		}

		// 尝试从媒体类型或型号确定磁盘类型
		mediaType := strings.ToLower(wmiDisk.MediaType)
		model := strings.ToLower(wmiDisk.Model)

		if strings.Contains(mediaType, "ssd") || strings.Contains(model, "ssd") || strings.Contains(model, "solid state") {
			disk.Type = "SSD"
		} else if strings.Contains(model, "nvme") {
			disk.Type = "NVMe"
			disk.Interface = "NVMe"
		} else if strings.Contains(mediaType, "fixed") || strings.Contains(mediaType, "hard disk") {
			disk.Type = "HDD"
		} else if strings.Contains(mediaType, "removable") {
			disk.Removable = true
			disk.Type = "Removable"
		}

		// 从接口检测可移动性
		if strings.Contains(strings.ToLower(wmiDisk.InterfaceType), "usb") {
			disk.Removable = true
		}

		disks = append(disks, disk)
	}

	return disks
}

// mapBusType 将Windows总线类型代码转换为接口名称
func mapBusType(busType uint16) string {
	busTypes := map[uint16]string{
		0:  "Unknown",
		1:  "SCSI",
		2:  "ATAPI",
		3:  "ATA",
		4:  "1394",
		5:  "SSA",
		6:  "FC",
		7:  "USB",
		8:  "RAID",
		9:  "iSCSI",
		10: "SAS",
		11: "SATA",
		12: "SD",
		13: "MMC",
		14: "Virtual",
		15: "File Backed Virtual",
		16: "Storage Spaces",
		17: "NVMe",
		18: "SCM",
	}

	if name, ok := busTypes[busType]; ok {
		return name
	}
	return fmt.Sprintf("Unknown (%d)", busType)
}
